package com.autumn.config.services.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.autumn.config.api.consts.ConfigureConsts.StatusConsts;
import com.autumn.config.api.dto.input.ApplicationInfoInput;
import com.autumn.config.api.dto.input.StatusInput;
import com.autumn.config.api.services.IApplicationInfoService;
import com.autumn.config.api.services.ICacheService;
import com.autumn.config.api.vo.ApplicationInfoValue;
import com.autumn.config.entities.ApplicationInfo;
import com.autumn.mybatis.criterion.LockModeEnum;
import com.autumn.util.AutoMapUtils;
import com.autumn.util.DataRollbackException;
import com.autumn.util.ExceptionUtils;
import com.autumn.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

/**
 * 应用信息服务实现
 *
 * @author 老码农
 * <p>
 * Description
 * </p>
 * @date 2017-12-31 00:22:40
 */
@Service(interfaceClass = IApplicationInfoService.class)
@Component
public class ApplicationInfoServiceImpl extends
        AbstractConfigurePageService<ApplicationInfo, ApplicationInfo, ApplicationInfoInput, ApplicationInfoInput, ApplicationInfoValue, ApplicationInfoValue>
        implements IApplicationInfoService {

    @Autowired
    private ICacheService cacheService;

    private void checkInput(ApplicationInfoInput input) {
        ExceptionUtils.checkNotNull(input, "input");
        if (StringUtils.isNullOrBlank(input.getAppId())) {
            ExceptionUtils.throwValidationException("应用id不能为空。");
        }
        if (StringUtils.isNullOrBlank(input.getAppName())) {
            ExceptionUtils.throwValidationException("应用名称不能为空。");
        }
    }

    private final static String APP_ID_FILED = "appId";
    private final static String APP_NAME_FILED = "appName";

    @Override
    @Transactional(rollbackFor = DataRollbackException.class)
    public ApplicationInfoValue add(ApplicationInfoInput input) {
        checkInput(input);
        if (this.exist(APP_ID_FILED, input.getAppId())) {
            ExceptionUtils.throwValidationException(String.format("应用id %s 已重复。", input.getAppId()));
        }
        if (this.exist(APP_NAME_FILED, input.getAppName())) {
            ExceptionUtils.throwValidationException(String.format("应用名称 %s 已重复。", input.getAppName()));
        }
        ApplicationInfo appInfo = AutoMapUtils.map(input, ApplicationInfo.class);
        if (appInfo.getSortId() == null) {
            appInfo.setSortId(1);
        }
        appInfo.insertAuditingInitialize();
        appInfo.setStatus(StatusConsts.STATUS_DRAFT);
        repository.insert(appInfo);
        return AutoMapUtils.map(appInfo, ApplicationInfoValue.class);
    }

    @Override
    @Transactional(rollbackFor = DataRollbackException.class)
    public ApplicationInfoValue modify(ApplicationInfoInput input) {
        checkInput(input);
        if (input.getId() == null) {
            ExceptionUtils.throwValidationException("Id 不能为空");
        }
        ApplicationInfo result = this.getQueryById(input.getId(), LockModeEnum.UPDATE);
        if (result == null) {
            ExceptionUtils.throwValidationException(String.format("名称 %s 的应用不存在。", input.getAppName()));
        }
        if (result.getStatus().equals(StatusConsts.STATUS_RELEASE)) {
            ExceptionUtils.throwValidationException(String.format("名称 %s 为发布状态，不能修改。", input.getAppName()));
        }
        if (!input.getAppId().equalsIgnoreCase(result.getAppId())) {
            if (this.exist(APP_ID_FILED, input.getAppId())) {
                ExceptionUtils.throwValidationException(String.format("应用id %s 已重复。", input.getAppId()));
            }
        }
        if (!input.getAppName().equalsIgnoreCase(result.getAppName())) {
            if (this.exist(APP_NAME_FILED, input.getAppName())) {
                ExceptionUtils.throwValidationException(String.format("应用名称 %s 已重复。", input.getAppName()));
            }
        }
        AutoMapUtils.map(input, result);
        result.updateAuditing();
        result.setStatus(StatusConsts.STATUS_DRAFT);
        repository.update(result);
        return AutoMapUtils.map(result, ApplicationInfoValue.class);
    }

    @Override
    @Transactional(rollbackFor = DataRollbackException.class)
    public ApplicationInfoValue updateStatus(StatusInput input) {
        ApplicationInfoValue output = super.updateStatus(input);
        if (output != null) {
            cacheService.deleteServiceInfo(output.getAppId());
        }
        return output;
    }

    @Override
    protected ApplicationInfo deleteById(Long id) {
        ApplicationInfo info = super.deleteById(id);
        if (info != null) {
            cacheService.deleteServiceInfo(info.getAppId());
        }
        return info;
    }
}
